﻿namespace LiteBlog.Components
{
    using System;
    using System.Globalization;
    using System.Linq;
    using LiteBlog.Common.Entities;
    using LiteBlog.Components.Contracts;
    using LiteBlog.Components.Enums;
    using LiteBlog.Repositories.Contracts;
    using LiteBlog.Components.Helpers;

    public class PostComp : BaseComp<IPostRepository>, IPostComp
    {
        public PostComp(IPostRepository data, ICacheComp cache) : base(data, cache)
        {        
        }
      
        public Post Load(string fileId)
        {
            var post = _cache.GetPost(fileId);
            if (post == null)
            {
                post = _data.Load(fileId);
                post.FormattedTime = post.Time.ToString(ConfigComp.DateFormat, CultureInfo.InvariantCulture);
                post.HighlightedContents = SyntaxHighlighter.Highlight(post.Contents);

                foreach (var c in post.Comments)
                    c.FormattedTime = c.Time.ToString(ConfigComp.DateFormat, CultureInfo.InvariantCulture);

                _cache.PutPost(fileId, post);
            }
            return post;
        }

        public MethodResult Save(Post post)
        {
            _data.Save(post);
            return MethodResult.SaveSuccess;
        }

        public DraftPost EditPublished(string fileId)
        {
            // allow edit published only once!
            string draftId = _data.GetDraftIdIfDraftExistsForPublishedPost(fileId);
            DraftPost draftPost;
            if (string.IsNullOrEmpty(draftId))
                draftPost = _data.EditPublished(fileId);
            else
                draftPost = LoadDraft(draftId);
            return draftPost;
        }

        public bool DeleteAttachment(string fileId, string docid)
        {
            var draftPost = LoadDraft(fileId);
            var document = draftPost.Documents.SingleOrDefault(doc => doc.Id == docid);
            if (document != null)
                draftPost.Documents.Remove(document);
            Save(draftPost);
            return draftPost.Type == DraftType.Published ? false : true;
        }

        private DraftPost LoadDraft(string fileId)
        {
            return (DraftPost)Load(fileId);
        }

        private void SaveDraft(Post post)
        {
            var draft = (DraftPost)post;
            if (draft == null)
                throw new InvalidOperationException();
            Save(draft);
        }
    }
}